#include "TcpServer.h"
#include "Acceptor.h"
#include "TcpConnection.h"
#include "EventLoop.h"
#include "ThreadPool.h"
#include <iostream>
#include <unistd.h>

using std::cout;
using std::endl;

ThreadPool *gPool = nullptr;

class MyTask
{
public:
    MyTask(const string &msg, const TcpConnectionPtr &con)
    : _msg(msg)
    , _con(con)
    {

    }
    void process()
    {
        _msg;
        //msg转接到MyTask的process函数中来处理即可
        //decode、compute、encode
        //....
        //....
        //...
        //数据在线程池中处理好了之后，应该是由线程池发送给
        //EventLoop，然后在EventLoop中将数据发给客户端
        //
        //1、线程池如何将数据发送给EventLoop
        //解答：也就是在写一个函数，称为sendInLoop，也就是线程池
        //将数据发到EventLoop
        //
        //2、线程池处理好业务逻辑之后，什么时候发过去呢？
        //解决：线程池处理好业务逻辑之后就可以将数据发给EventLoop
        //
        //3、线程池中的线程需要通知EventLoop线程进行接收数据？
        //也就是线程池中的线程需要与EventLoop线程进行通信？
        //也就是两个线程之间如何进行通信呢？
        //解答:进程或者线程之间进行通信的方法是eventfd
        _con->sendInLoop(_msg);
    }

private:
    string _msg;
    TcpConnectionPtr _con;
};

void onNewConnection(const TcpConnectionPtr &con)
{
    cout << con->toString() << " has connected!!!" << endl;
}

void onMessage(const TcpConnectionPtr &con)
{
    //接收客户端的数据（ready）
    string msg = con->receive();
    cout << ">>recv client msg = " << msg << endl;

    //得到客户端发送过来的数据之后，业务逻辑的处理还没有进行
    //decode、compute、encode
    //如果业务逻辑的处理非常的麻烦，非常的耗时，那么该版本会
    //遇到瓶颈
    //就需要将业务逻辑的处理交给线程池，可以让多个线程同时处理
    //业务逻辑
    
    MyTask task(msg, con);

    gPool->addTask(std::bind(&MyTask::process, task));
}

void onClose(const TcpConnectionPtr &con)
{
    cout << con->toString() << " has closed!!!" << endl;
}

void test()
{
    ThreadPool pool(4, 10);
    pool.start();

    gPool = &pool;

    TcpServer server("127.0.0.1", 8888);

    server.setAllCallback(std::move(onNewConnection)
                          , std::move(onMessage)
                          , std::move(onClose));

    server.start();//启动服务器
}

int main(int argc, char **argv)
{
    test();
    return 0;
}

